package com.gzl.autotest.testcase;

import com.gzl.autotest.entity.CaseData;
import com.gzl.autotest.entity.Variable;
import com.gzl.autotest.utils.*;
import org.apache.log4j.Logger;
import org.testng.annotations.*;
import org.testng.annotations.Optional;
import com.alibaba.fastjson.JSONObject;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.regex.Pattern;

public class BaseCase {
    public static Logger logger = Logger.getLogger(BaseCase.class);

    // 保存所有用例对象
    public static List<CaseData> cases = new ArrayList<CaseData>();

    // 存放变量对象的列表
    public static List<Variable> variables = new ArrayList<Variable>();

    // 替换符,匹配形如${param}的字符串
    public static Pattern replaceParamPattern = Pattern.compile("\\$\\{(.*?)\\}");

    // 存放全局变量的map
    public static Map<String, String> globalVariableMap = new HashMap<>();

    public static Properties properties = new Properties();

    static {
        try {
            // 解决properties中中文乱码
            InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("src\\test\\resources\\config.properties"), "GBK");
            properties.load(inputStreamReader);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    @Parameters({ "excelPath", "dataSheetName", "variableSheetName"})
    @BeforeTest
    public void readDataFromExcel(@Optional("caseData/caseData.xlsx") String excelPath, @Optional("case") String dataSheetName, @Optional("variables") String variableSheetName){
        logger.info("excelPath: " + excelPath);
        logger.info("dataSheetName: " + dataSheetName);
        logger.info("variableSheetName: " + variableSheetName);
        cases = ExcelUtil.loadExcel(excelPath, dataSheetName, CaseData.class);
        variables = ExcelUtil.loadExcel(excelPath, variableSheetName, Variable.class);
//        logger.info("读取文件获取到的cases对象：" + cases);
//        logger.info("读取文件获取到的variables对象：" + variables);
        VariableUtil.loadVariablesToMap(variables);
    }

    @DataProvider(name = "datasFromExcel")
    public Iterator<Object[]> getCaseDatas(){
        List<Object[]> apiDataList = new ArrayList<Object[]>();
        for (CaseData caseData : cases){
            apiDataList.add(new Object[] { caseData });
        }
        return apiDataList.iterator();
    }

    @Test(dataProvider = "datasFromExcel", timeOut = 600000)
    public void test(CaseData caseData){
        // 获取对象中的数据
        String url = caseData.getUrl();
        String requestType = caseData.getRequestType();
        String headers = caseData.getHeaders();
        // String cookies = caseData.getCookies();  // 暂未涉及
        String parameters = caseData.getParameters();
        // String uploadFile = caseData.getUploadFile();  // 暂未涉及
        String initSql = caseData.getInitSql();
        String globalVariables = caseData.getGlobalVariables();
        String assertFields = caseData.getAssertFields();

        logger.info("url: " + url);
        logger.info("requestType: " + requestType);
        logger.info("headers: " + headers);
        logger.info("处理前的请求参数是："+parameters);

        // 替换入参中的非关联参数
        parameters = VariableUtil.variableSubstitution(parameters);
        // 替换入参中的关联参数
        parameters = GlobalVariableUtil.substitutionGlobalVariable(parameters);
        logger.info("处理后的请求参数是："+parameters);

        logger.info("initSql: " + initSql);
        logger.info("globalVariables: " + globalVariables);
        logger.info("assertFields: " + assertFields);

        url = "http://" + properties.getProperty("project.ip").trim() + ":"+ properties.getProperty("project.port").trim() + url;
        logger.info(url);
        // 发送请求
        String actual = null;       //请求返回结果
        JSONObject headsJsonObject = JSONObject.parseObject(headers);
        // 根据请求头判断是发送json还是非json
        if (headsJsonObject!=null && "application/json".equals(headsJsonObject.getString("Content-Type"))){
            // 解析json格式字符串为JSONObject
            JSONObject paramJsonObject = JSONObject.parseObject(parameters);
            // 请求
            actual = HttpRequestJsonUtil.sendRequest(url, requestType, paramJsonObject,headsJsonObject);
            logger.info("json请求返回结果： " + actual);

        } else {
            HashMap<String, String> params = new HashMap<String, String>();
            // 解析json格式字符串为JSONObject
            JSONObject jsonObject = JSONObject.parseObject(parameters);
            // JSONObject转换为map
            Set<String> keys = jsonObject.keySet();
            for (String key : keys) {
                params.put(key, jsonObject.getString(key));
            }
            // 请求，获取结果
            actual = HttpRequestUtil.sendRequest(url, requestType, params);
            logger.info("k-v请求返回结果： " + actual);
        }
        //保存全局变量
        if(globalVariables != null && globalVariables.length() > 0){
            if(actual != null && actual.trim().length() > 0){
                JSONObject actualJson = JSONObject.parseObject(actual);
                String[] split = globalVariables.split("=");
                String glovalVariableName = split[0];
                String[] glovalVariableValue = split[1].split("\\.");
                glovalVariableValue[glovalVariableValue.length - 1].substring(0, glovalVariableValue[glovalVariableValue.length - 1].length() - 1);     //去掉最后一个;
                for (int i = 1; i < glovalVariableValue.length; i++) {
                    actualJson = actualJson.getJSONObject(glovalVariableValue[i]);
                }
                globalVariableMap.put(glovalVariableName, actualJson.toJSONString());
            }
        }
        // 是否需要断言关键字段
        if (StringUtil.isNotNullAndEmpty(assertFields)){
            AssertUtil.getFieldsAssertRes(actual, assertFields);
        }

        // 执行初始化sql
        if (initSql != null && initSql.trim().length() > 0) {
            // 替换sql中的参数
            initSql = VariableUtil.variableSubstitution(initSql);
            // 调用方法
            InitSqlUtil.doInitSql(initSql);
        }
    }

}
